
#include <QtCore>
#include "gps_point.h"

GPS_point::GPS_point() :
    QGeoCoordinate()
{
    initialize( QDateTime::currentDateTime(), 0, 0, 0, GPS_dop() );
}

// ... from date, position, precision and speed ...
GPS_point::GPS_point(const QGeoCoordinate &c,
                    const QDateTime& t,
                    double s,
                    int h,
                    int v,
                    const GPS_dop& d) :
    QGeoCoordinate( c )
{
    initialize( t, s, h, v, d);
}

// ... frome xisting QGeoCoordinate ...
GPS_point::GPS_point (const QGeoCoordinate& c):
    QGeoCoordinate(c)
{
    initialize( QDateTime::currentDateTime(), 0, 0, 0, GPS_dop() );
}

// ... from another point!
GPS_point::GPS_point(const GPS_point& other) :
    QGeoCoordinate( other )
{
    _timestamp = other._timestamp;
    _dop = other._dop;
    _speed = other._speed;
    _h_precision_mt = other._h_precision_mt;
    _v_precision_mt = other._v_precision_mt;
    _magneticVariation = other._magneticVariation;
    _direction = other._direction;
    _steepness = other._steepness;
}

void GPS_point::initialize(const QDateTime& t,
                           double s,
                           int h,
                           int v,
                           const GPS_dop& d )
{
    setSpeed( s );
    setPrecision( h, v );
    setDop( d );
    setTimestamp( t );
    setMagneticVariation(0.0);
    setDirection(0.0);
    setSteepness(0.0);
}

GPS_point::~GPS_point()
{
}


double GPS_point::speed() const
{
    return _speed;
}
void GPS_point::setSpeed(double s)
{
    _speed = s > 0.0 ? s : 0.0;
}

int GPS_point::h_precision() const
{
    return _h_precision_mt;
}
int GPS_point::v_precision() const
{
    return _v_precision_mt;
}
void GPS_point::precision(int& h, int& v) const
{
    h = h_precision();
    v = v_precision();
}
void GPS_point::setPrecision(int h, int v)
{
    _h_precision_mt = h > 1 ? h : 1;
    _v_precision_mt = v > 1 ? v : 1;
}

QDateTime GPS_point::timestamp() const
{
    return _timestamp;
}
void GPS_point::setTimestamp(const QDateTime& d)
{
    _timestamp = d;
}

GPS_dop GPS_point::dop() const
{
    return _dop;
}

void GPS_point::setDop( const GPS_dop& d)
{
    _dop = d;
}

void GPS_point::translate(double lat, double lon)
{
    setLatitude( latitude() + lat);
    setLongitude( longitude() + lon);
}

bool GPS_point::isOverlapping(const GPS_point& pt) const
{
    qreal distance = distanceTo( pt );
    return distance <= (_h_precision_mt+pt._h_precision_mt);
}

qreal GPS_point::direction() const
{
    return _direction;
}

void GPS_point::setDirection(qreal d)
{
    _direction = d;
}

// get/set magvar
qreal GPS_point::magneticVariation() const
{
    return _magneticVariation;
}

void GPS_point::setMagneticVariation(qreal d)
{
    _magneticVariation = d;
}

qreal GPS_point::steepness() const
{
    return _steepness;
}

void GPS_point::setSteepness(qreal s)
{
    _steepness = s;
}

QString GPS_point::serialize() const
{
    return QString("%1 %2 %3 %4 %5 %6 %7 %8 %9")
                        .arg( latitude(), 0, 'f' )
                        .arg( longitude(), 0, 'f' )
                        .arg( altitude(), 0, 'f' )
                        .arg( speed(), 0, 'f' )
                        .arg( h_precision())
                        .arg( v_precision() )
                        .arg( direction(), 0, 'f' )
                        .arg( magneticVariation(), 0, 'f' )
                        .arg( steepness(), 0, 'f', 2 )+
           "\"" + timestamp().toString( Qt::ISODate) + "\" " +
           dop().serialize();
}

GPS_point* GPS_point::unserialize(QTextStream& stream )
{
    GPS_point* pt = new GPS_point();
    double lat, lon, alt, dir, magvar, speed, stpn;
    int hp, vp;
    QDateTime timestamp;
    QString ts;
    stream >> lat;
    stream >> lon;
    stream >> alt;
    stream >> speed;
    stream >> hp;
    stream >> vp;
    stream >> dir;
    stream >> magvar;
    stream >> stpn;
    stream >> ts;
    ts.chop(1);
    ts = ts.mid(1);
    timestamp = QDateTime::fromString(ts, Qt::ISODate);
    pt->setDop( GPS_dop::unserialize( stream ) );

    pt->setLatitude( lat );
    pt->setLongitude( lon );
    pt->setAltitude( alt );
    pt->setSpeed( speed );
    pt->setPrecision( hp, vp);
    pt->setTimestamp( timestamp );
    pt->setDirection( dir );
    pt->setMagneticVariation( magvar );
    pt->setSteepness( stpn );
    return pt;
}
